#include "sys.h"

void Delay_us(uint32_t nus)
{
    uint32_t ticks, told, tnow, tcnt, reload;
    told = SysTick->VAL;
    reload = SysTick->LOAD;
    ticks = SystemCoreClock / 1000000 * nus;
    tcnt = 0;
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += (told - tnow);
            }
            else
            {
                tcnt += ((reload - tnow) + told);
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                break;
            }
        }
    }
}
void Delay_us_with_Break_by_Function(uint32_t nus, uint8_t(*fun(void)))
{
    uint32_t ticks, told, tnow, tcnt, reload;
    told = SysTick->VAL;
    reload = SysTick->LOAD;
    ticks = SystemCoreClock / 1000000 * nus - 37;
    tcnt = 0;
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += (told - tnow);
            }
            else
            {
                tcnt += ((reload - tnow) + told);
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                break;
            }
            if (fun())
            {
                break;
            }
        }
    }
}
/* 因为pValue为真则返回1 因为时间到了则返回0*/
uint8_t Delay_us_With_Break_by_Value(uint32_t nus, volatile uint8_t *pValue)
{
    uint32_t ticks, told, tnow, tcnt, reload;
    told = SysTick->VAL;
    reload = SysTick->LOAD;
    ticks = SystemCoreClock / 1000000 * nus - 37;
    tcnt = 0;
    while (1)
    {
        tnow = SysTick->VAL;
        if (tnow != told)
        {
            if (tnow < told)
            {
                tcnt += (told - tnow);
            }
            else
            {
                tcnt += ((reload - tnow) + told);
            }
            told = tnow;
            if (tcnt >= ticks)
            {
                return 0;
            }
            if (*pValue)
            {
                return 1;
            }
        }
    }
}
uint16_t CRC16_CCITT_FALSE(uint8_t *puchMsg, uint16_t usDataLen)
{
    uint16_t wCRCin = 0xFFFF;
    uint16_t wCPoly = 0x1021;
    uint8_t wChar = 0;
    while (usDataLen--)
    {
        wChar = *(puchMsg++);
        wCRCin ^= (wChar << 8);
        for (int i = 0; i < 8; i++)
        {
            if (wCRCin & 0x8000)
            {
                wCRCin = (wCRCin << 1) ^ wCPoly;
            }
            else
            {
                wCRCin = wCRCin << 1;
            }
        }
    }
    return (wCRCin);
}
void MCU_Standby()
{
    /* JLink引脚重置为普通IO */
    LL_GPIO_AF_DisableRemap_SWJ();

    /* 复原所有IO为模拟输入 */
    LL_GPIO_DeInit(GPIOA);
    LL_GPIO_DeInit(GPIOB);
    LL_GPIO_DeInit(GPIOC);

    /* 将PA0设置为唤醒端口，上升沿唤醒*/
    LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN1);
    /*  PDDS 决定进Stop还是Standby LPDS 决定进Stop时关不关1.8V电源*/
    LL_PWR_SetPowerMode(LL_PWR_MODE_STANDBY);
    /* 允许进入深度睡眠模式 */
    LL_LPM_EnableDeepSleep();
    /* 清除标志位 */
    LL_PWR_ClearFlag_SB();
    LL_PWR_ClearFlag_WU();
    __WFI();
    __NOP();
    __NOP();
    __NOP();
    __NVIC_SystemReset();
}

void SystemPoweronInitWithHSI(void)
{
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
    NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
    LL_GPIO_AF_Remap_SWJ_NOJTAG();
    SystemClockConfigHSI();
}
void SystemPoweronInitWithHSE(void)
{
    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_AFIO);
    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
    NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
    LL_GPIO_AF_Remap_SWJ_NOJTAG();
    SystemClockConfigHSE();
}
void SystemClockConfigHSE(void)
{
    // 设置Flash速度
    LL_FLASH_SetLatency(LL_FLASH_LATENCY_2);
    if (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_2)
    {
        while (1)
            ;
    }
    // 外部时钟
    LL_RCC_HSE_Enable();
    while (LL_RCC_HSE_IsReady() != 1)
    {
    }
    // 倍频配置
    LL_RCC_HSE_EnableCSS();
    LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE_DIV_1, LL_RCC_PLL_MUL_9);
    LL_RCC_PLL_Enable();
    while (LL_RCC_PLL_IsReady() != 1)
    {
    }
    // 外设分频配置
    LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1);
    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_2);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL);
    while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_PLL)
    {
    }
    // Systick配置
    LL_Init1msTick(72000000);
    LL_SYSTICK_SetClkSource(LL_SYSTICK_CLKSOURCE_HCLK);
    LL_SetSystemCoreClock(72000000);
}
void SystemClockConfigHSI(void)
{
    /* Flash速度 */
    LL_FLASH_SetLatency(LL_FLASH_LATENCY_0);
    while (LL_FLASH_GetLatency() != LL_FLASH_LATENCY_0)
    {
    }

    /* HSI内部高速时钟频率调整，可调整到8MHz +- 1% */
    LL_RCC_HSI_SetCalibTrimming(16);
    /* 打开8MHz内部高速时钟 */
    LL_RCC_HSI_Enable();
    /* 等待时钟启动 */
    while (LL_RCC_HSI_IsReady() != 1)
    {
    }

    /* 设置AHB = 8MHz APB1 = 1MHz ABP2 = 1MHz*/
    LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_8);
    LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1);
    LL_RCC_SetAPB2Prescaler(LL_RCC_APB2_DIV_1);
    /* 正式切换时钟为HSI */
    LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSI);
    /* Wait till System clock is ready */
    while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI)
    {
    }
    /* 保存时钟值，以作后用 */
    LL_SetSystemCoreClock(1000000);

    /* 初始化1ms时钟SysTick */
    LL_Init1msTick(1000000);

    /* 设置ADC时钟 */
    LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSRC_PCLK2_DIV_2);
}
void RTCClockConfig(void)
{
}
void GPIO_Init(GPIO_Init_Param_Typedef *pGPIO_Init_Param)
{
    uint8_t i;

    // 初始化IO口
    for (i = 0; i < 64; i++)
    {
        // 退出循环条件
        if ((pGPIO_Init_Param + i)->GPIOx == 0)
        {
            break;
        }

        // 根据需要打开时钟
        switch ((uint32_t)(pGPIO_Init_Param + i)->GPIOx)
        {
        case (uint32_t)GPIOA:
            LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOA);
            break;
        case (uint32_t)GPIOB:
            LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOB);
            break;
        case (uint32_t)GPIOC:
            LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOC);
            break;
        case (uint32_t)GPIOD:
            LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOD);
            break;
            // case (uint32_t)GPIOE:
            //     LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_GPIOE);
            //     break;
        }
        // 初始化IO口模式
        LL_GPIO_Init((pGPIO_Init_Param + i)->GPIOx, (LL_GPIO_InitTypeDef *)&((pGPIO_Init_Param + i)->GPIO_Param));

        // 设置GPIO PIN电平
        if ((pGPIO_Init_Param + i)->InitValue == 1)
        {

            LL_GPIO_SetOutputPin((pGPIO_Init_Param + i)->GPIOx, (pGPIO_Init_Param + i)->GPIO_Param.Pin);
        }
        else
        {
            LL_GPIO_ResetOutputPin((pGPIO_Init_Param + i)->GPIOx, (pGPIO_Init_Param + i)->GPIO_Param.Pin);
        }
    }
}
void SystemPoweronInit(void)
{
    SystemPoweronInitWithHSE();
    RTCClockConfig();
}